/************************************************************************** 
 * @name: LcdShow.c
 * @brief: 这是用于访问ARM开发板的LCD屏，目的是学习系统IO的关于文件访问接口
 * @date: 2025/01/07 
 * @author: boluzs@163.com
 * @note: 
 *          1. ARM开发板搭载的是linux系统，而linux系统下有关于帧缓冲设备的驱动子系统FrameBuffer
 *          2. 驱动子系统FrameBuffer已经提供了关于LCD显示设备的设备文件 设备文件的路径"/dev/fb0" 
 *          3. ARM开发板搭载的LCD屏的物理尺寸是7寸，LCD屏的分辨率是800*480，LCD屏色深是32bit
 *          4. LCD屏的每个像素点的色深是32bit，所以每个像素点是4字节，每个像素点的结构是ARGB
 *          5. 像素点的颜色显示是依赖RGB颜色分量，每种颜色分量都占8bit，每种颜色分量的范围0~255
 *          6. 需要使用交叉编译arm-linux-gcc对源文件进行编译，把ARM平台的可执行文件下载到ARM开发板
 * @version: 1.0.0
 * @Copyright (c) 2025 by boluzs@163.com, All Rights Reserved. 
 **************************************************************************/
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/mman.h>

//为了提高程序的可移植性，LCD的设备文件的路径通过宏定义实现
#define  LCD_DEV   "/dev/fb0"

int main()
{
    //1.打开LCD，linux系统下把硬件设备抽象为文件，所以可以访问硬件设备的设备文件
    int lcd_fd = open(LCD_DEV,O_RDWR);

    //错误处理
    if(-1 == lcd_fd)
    {
        fprintf(stderr,"open lcd error,errno = %d,%s\n",errno,strerror(errno));
        exit(-1);
    }
    //第二步：申请内存映射空间
    int*mmap_star =  (int*)mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,lcd_fd,0);
    if(mmap_star == (int *)-1 )
    {
        printf("内存映射失败！\n");
        return -1;
    }
    else
    {
        printf("内存映射成功！\n");
    }

    //2.准备颜色数据 比如白色在RGB颜色对照表中对应的值是 0xFFFFFF 
    int buf[800*480] ={0};
    for (size_t i = 0; i < 800*480; i++)
    {
       buf[i] = 0xFFFFFF; //ARGB 
    }
    

    //3.向LCD屏的设备文件中写入准备好的颜色数据
    write(lcd_fd,buf,800*480*4);

    //4.关闭LCD,不会影响已经写入到LCD的设备文件中颜色数据
    close(lcd_fd);

    return 0;
}